package jeopardy.common.protocol.useraccount;

import java.util.Arrays;
import java.util.regex.Pattern;

import jeopardy.common.Consts;

import com.google.gson.Gson;

public class UserAccountUtils {
	protected static final String METHOD_CREATE = "CREATE";
	protected static final String METHOD_AUTH = "AUTH";
	
	protected static final Pattern usernamePattern = Pattern.compile("^[a-z0-9A-Z]{4,12}$");
	protected static final Pattern passwordPattern = Pattern.compile("^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&+=]).{8,32}$");
		
	private static Gson gson = new Gson();
	
	public static byte[] reqToNetworkMsg(UserAccountRequest uar){
		byte bytes[] =  gson.toJson(uar).getBytes();
		byte bytesWDelim[] = Arrays.copyOf(bytes, bytes.length + 1);
		bytesWDelim[bytes.length] = Consts.MSG_DELIM;
		
		return bytesWDelim;
	}
	
	public static int parseUserAccountResponse(byte[] res) throws Exception {
		if(res == null || res.length != 2 || res[1] != Consts.MSG_DELIM){
			throw new Exception("invalid account response");
		}
		if(res[0] < 0 || res[0] > 3){
			throw new Exception("invalid account response");
		}
		return res[0];
	}
	
	public static UserAccountRequest parseUserAccountRequest(byte[] req) throws Exception {
		UserAccountRequest uar = gson.fromJson(new String(req, 0, req.length), UserAccountRequest.class);
		
		if(!validateMethodString(uar.method)){
			throw new Exception("invalid method");
		}
		if(uar.method.equals(METHOD_AUTH)){
			if(!validateUserString(uar.user)){
				throw new Exception ("invalid user");
			}
		}

		if(uar.method.equals(METHOD_AUTH)){
			if(!validatePasswordString(uar.password)){
				throw new Exception("invalid password string");
			}
		}
		
		return uar;
	}

	public static UserAccountRequest createUserAuthRequest(String user, char[] pass) throws Exception{
		
		UserAccountRequest lookup = new UserAccountRequest();
		lookup.method = METHOD_AUTH;
		lookup.user = user;
		lookup.password = pass;
		return lookup;
	}
	
	public static UserAccountRequest createUserCreateRequest(String user, char[] password) throws Exception{
		
		UserAccountRequest create = new UserAccountRequest();
		create.method = METHOD_CREATE;
		create.user = user;
		create.password = password;
		
		return create;
		
	}
	
	public static boolean validateMethodString(String method){
		if(method == null){
			return false;
		}
		
		return (method.equals(METHOD_CREATE) || method.equals(METHOD_AUTH));
	}
	
	/**
	 * Validates the user string. <br>
	 * User string has to be:<br>
	 * 	1.  4 - 12 characters long <br>
	 *  2.  Consist of character set from [a-z], [A-Z], or [0-9]
	 * 
	 * @param user
	 * @return boolean indicating whether given <code>user</code> param is a valid user string
	 */
	public static boolean validateUserString(String user){
		if(user == null){
			return false;
		}
		
		return usernamePattern.matcher(user).matches();
	}
	
	/**
	 * Validates the password string. <br>
	 * Password string has to be...<br>
	 *  1. between 8 to 32 characters
	 *  2. Must contain at least 1 of each: [a-z], [A-Z], [0-9], [!@#$%^&+=]
	 * @param password
	 * @return
	 */
	public static boolean validatePasswordString(char[] password){
		if(password == null){
			return false;
		}
		
		return passwordPattern.matcher(new String(password)).matches();
	}
}
